import json

import allure
from jsonpath_ng import parse

from utils.logger import log


class Assertions:

	@staticmethod
	def contains_assert(expected, actual):
		"""
		包含预期
		:param expected: 预期结果
		:param actual: 返回结果
		:return: bool
		"""
		for key, value in expected.items():
			result = [match.value for match in parse(f'$.{key}').find(json.loads(actual.text))]
			if value in result:
				allure.attach(f"contains预期结果: {expected} \n实际结果: {result}", '响应代码断言结果:成功', attachment_type=allure.attachment_type.TEXT)
				log.info("contains断言成功：接口返回值【%s】包含【%s】" % (result, value))
				return True
			else:
				allure.attach(f"contains预期结果: {expected} \n实际结果: {result}", '响应代码断言结果:失败', attachment_type=allure.attachment_type.TEXT)
				log.error("contains断言失败：接口返回值【%s】不包含【%s】" % (result, value))
				return False

	@staticmethod
	def eq_assert(expected, actual):
		"""
		等于预期
		:param expected: 预期结果
		:param actual: 返回结果
		:return: bool
		"""
		for key, value in expected.items():
			result = [match.value for match in parse(f'$.{key}').find(json.loads(actual.text))][0]
			if value == result:
				allure.attach(f"eq预期结果: {expected} \n实际结果: {result}", '响应代码断言结果:成功',
				              attachment_type=allure.attachment_type.TEXT)
				log.info("equal断言成功：接口返回值【%s】等于【%s】" % (result, value))
				return True
			else:
				allure.attach(f"eq预期结果: {expected} \n实际结果: {result}", '响应代码断言结果:失败',
				              attachment_type=allure.attachment_type.TEXT)
				log.error("equal断言失败：接口返回值【%s】不等于【%s】" % (result, value))
				return False

	@staticmethod
	def ne_assert(expected, actual):
		"""
		不等于预期
		:param expected: 预期结果
		:param actual: 返回结果
		:return: bool
		"""
		for key, value in expected.items():
			result = [match.value for match in parse(f'$.{key}').find(json.loads(actual.text))][0]
			if value != result:
				allure.attach(f"ne预期结果: {expected} \n实际结果: {result}", '响应代码断言结果:成功',
				              attachment_type=allure.attachment_type.TEXT)
				log.info("ne断言成功：接口返回值【%s】不等于【%s】" % (result, value))
				return True
			else:
				allure.attach(f"ne预期结果: {expected} \n实际结果: {result}", '响应代码断言结果:失败',
				              attachment_type=allure.attachment_type.TEXT)
				log.error("ne断言失败：接口返回值【%s】等于【%s】" % (result, value))
				return False

	def assert_result(self, expected, response):
		log.info(f'测试预期结果：{expected}')
		flag = True
		for ex in expected:
			for key, value in ex.items():
				if key == 'contains':
					flag = self.contains_assert(value, response)
				elif key == 'eq':
					flag = self.eq_assert(value, response)
				elif key == 'ne':
					flag = self.ne_assert(value, response)

			if not flag:
				break
		log.info(f'测试结果: {"PASSED" if flag else "FAILED"}')
		assert flag
